package com.suieqian.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.suieqian.dto.req.UserReq;
import com.suieqian.dto.resp.UserResp;
import com.suieqian.entity.Role;
import com.suieqian.entity.User;
import com.suieqian.entity.UserRoleRef;
import com.suieqian.enums.DelStatusEnum;
import com.suieqian.service.IRoleService;
import com.suieqian.service.IUserRoleRefService;
import com.suieqian.service.IUserService;
import com.suieqian.service.impl.FastDFSClientImpl;
import com.suieqian.util.ExcelUtils;
import com.suieqian.util.FileUtil;
import com.suieqian.util.Message;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author: Lishuai
 */
@Api(tags = "用户管理接口")
@Controller
@RequestMapping("/api/userController")
@Slf4j
public class UserController {

    @Resource
    private IUserService userService;

    @Resource
    private IUserRoleRefService userRoleRefService;

    @Resource
    private IRoleService roleService;

    @Resource
    private FastDFSClientImpl fastDFSClient;

    @ApiOperation("用户列表")
    @PostMapping(value = "/listPage")
    @ResponseBody
    public Message<Message.PageResp<UserResp>> listPage(UserReq userReq) {
        try {
            IPage<User> page = new Page<>(userReq.getPageNo(), userReq.getPageSize());
            LambdaQueryWrapper<User> lqw = Wrappers.lambdaQuery();
            lqw.eq(User::getDelStatus, DelStatusEnum.NORMAL.getCode())
                    .eq(StrUtil.isNotBlank(userReq.getPhone()), User::getPhone, userReq.getPhone())
                    .like(StrUtil.isNotBlank(userReq.getName()), User::getName, userReq.getName())
                    .orderByDesc(User::getUserId);
            IPage<User> rsPage = userService.page(page, lqw);

            List<User> userList = rsPage.getRecords();
            if (CollUtil.isEmpty(userList)) {
                return Message.success(rsPage, UserResp.class);
            }
            Map<Long, String> roleNameMap = new HashMap<>();
            LambdaQueryWrapper<UserRoleRef> lqwUserRoleRef = Wrappers.lambdaQuery();
            lqwUserRoleRef.in(UserRoleRef::getUserId, userList.stream().map(item -> item.getUserId()).collect(Collectors.toList()));
            List<UserRoleRef> userRoleRefList = userRoleRefService.list(lqwUserRoleRef);
            if (CollUtil.isNotEmpty(userRoleRefList)) {
                Map<Long, List<UserRoleRef>> userRoleRefMap = userRoleRefList.stream().collect(Collectors.groupingBy(UserRoleRef::getUserId));
                for (Map.Entry<Long, List<UserRoleRef>> entry : userRoleRefMap.entrySet()) {
                    List<Long> roleIds = entry.getValue().stream().map(item -> item.getRoleId()).collect(Collectors.toSet()).stream().collect(Collectors.toList());
                    List<Role> roleList = roleService.listByIds(roleIds);
                    if (CollUtil.isNotEmpty(roleList)) {
                        String roleName = roleList.stream().map(item -> item.getRoleName()).collect(Collectors.joining(","));
                        roleNameMap.put(entry.getKey(), roleName);
                    }
                }
            }
            List<UserResp> userRespList = userList.stream().map(item -> {
                UserResp userResp = BeanUtil.copyProperties(item, UserResp.class);
                userResp.setRoleName(Objects.nonNull(roleNameMap.get(item.getUserId())) ? roleNameMap.get(item.getUserId()) : "");
                return userResp;
            }).collect(Collectors.toList());

            IPage<UserResp> resultPage = new Page<>();
            BeanUtil.copyProperties(rsPage, resultPage, "records");
            resultPage.setRecords(userRespList);
            return Message.success(resultPage, UserResp.class);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Message.error("获取用户列表失败");
        }
    }

    @ApiOperation("保存编辑用户")
    @PostMapping(value = "/addWithModUser")
    @ResponseBody
    public Message<Boolean> addWithModUser(@RequestBody UserReq userReq) {
        try {
            if (Objects.isNull(userReq.getUserId())) {
                userService.save(userReq);
            } else {
                userService.editUser(userReq);
            }
            return Message.success(true);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Message.error("保存编辑用户失败");
        }
    }

    @ApiOperation("删除用户")
    @PostMapping(value = "/deleteUser")
    @ResponseBody
    public Message<Boolean> deleteUser(Long delUserId) {
        try {
            userService.deleteUser(delUserId);
            return Message.success(true);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Message.error("删除用户失败");
        }
    }

    @ApiOperation("重置用户密码")
    @RequestMapping(value = "/modifyUserPwd", method = RequestMethod.POST)
    @ResponseBody
    public Message<Boolean> modifyUser(Long userId) {
        try {
            userService.modifyUserPwd(userId);
            return Message.success(true);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Message.error("重置用户密码失败");
        }
    }


    /**
     * 批量导入
     */
    @ApiOperation("批量导入")
    @PostMapping("/uploadExcel")
    public Message<Boolean> uploadExcel(@RequestPart("file") MultipartFile file) {
        List<Map<Integer, String>> list = null;
        try {
            list = ExcelUtils.read(file);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        if (CollectionUtils.isEmpty(list)) {
            return Message.success(true);
        }
        List<User> wasteList = new ArrayList<>();
        Date nowDate = new Date();
        String[] typeFlag = {null};
        String[] sourceFlag = {null};
        for (int i = 0; i < list.size(); i++) {
            Map<Integer, String> map = list.get(i);
        }
        return Message.success(true);
    }

    private String replaceStr(String str) {
        if (Objects.isNull(str)) {
            return null;
        }
        return str.replaceAll("\n", " ");
    }

    /**
     * 批量导出
     */
    @ApiOperation("批量导出")
    @GetMapping("/outExcel")
    public Message<Boolean> outExcel(HttpServletResponse response) {
        try {
            ExcelUtils.write(response, "用户管理", "sheet单1", UserResp.class, new ArrayList<>());
            return Message.success(true);
        } catch (Exception e) {
            log.error("批量导出失败", e);
            return Message.success(false);
        }
    }

    /**
     * 下载二维码 做个兼容，对生成二维码失败的从新生成一个
     */
    @ApiOperation("下载二维码")
    @GetMapping("/downloadQr")
    public Message<Boolean> downloadQr(HttpServletResponse response, @RequestParam @ApiParam("id") Long id) {
        try {
            byte[] bytes = fastDFSClient.downloadFile("address");
            FileUtil.downloadFile(bytes, "code", ".png", response);
            return Message.success(true);
        } catch (Exception e) {
            log.error("下载二维码失败", e);
            return Message.success(false);
        }
    }
}
